/*
 * send_1mbps.c
 * Created on November 29, 2005; 7:10 PM
 * by vramadurai
 */

/************ System Header Files ***************/
#include <stdio.h>
#include <stdlib.h>

/************ Private Header Files **************/
#include "HsTypes.h"
#include "PhyDebug.h"
#include "PhyStruct.h"
#include "PmdGlobals.h"
#include "PhyConstants.h"
#include "tables.h"
#include "tx_functions.h"
#include "iqdma_3500.h"
#include "icrdefs_3500.h"

void
send_1mbps(
				struct HS_PhyTx11bStr  *HS_PhyTx11bPtrTh1,
                hs_int16_t  * restrict ssDBPSKTbl,
                ePHYSTATES_TH  *ePhyState,
                hs_uint8_t *ucStateTable1Bit,
                hs_int16_t * psTxDtoAStartI,
                hs_int16_t * psTxDtoAStartQ,
                hs_uint32_t *crctab,
                hs_uint16_t usLength,
                hs_uint8_t	*psPayloadByte
             )
{
	hs_uint32_t crc;
	hs_int16_t zeros[16]= {0};
	hs_int32_t  crc_count;
    hs_uint8_t ucBit;
    hs_uint16_t usDiffSymbIndex;
	hs_int32_t	siPayloadBitCount;
	hs_uint8_t	ucBytePayload;
	hs_int32_t	siPayloadByteCount;
	hs_uint8_t ucScramState;
    hs_uint8_t ucInputBit;
	hs_uint8_t ucPrevSymb;
    hs_int32_t subbuff_toggle;

    hs_int16_t * psTxOut;
    hs_int16_t * psTxOutDtoAPtrI;
    hs_int16_t * psTxOutDtoAPtrQ;

    hs_int32_t i;
    //int tic1, tic2;

	siPayloadBitCount = 0;
	siPayloadByteCount = 0;
	ucScramState = HS_PhyTx11bPtrTh1->ucScramState;
	ucPrevSymb = HS_PhyTx11bPtrTh1->ucPrevSymb;

	psTxOutDtoAPtrI = HS_PhyTx11bPtrTh1->psTxDtoABufferI;
    psTxOutDtoAPtrQ = HS_PhyTx11bPtrTh1->psTxDtoABufferQ;

    subbuff_toggle = HS_PhyTx11bPtrTh1->subbuff_toggle;

	crc = 0xFFFFFFFFU;
	crc_count = 0;

    while(1){

    	//tic1 = __sb_cfsr(MACH_CYC);

		// CRC
		if(siPayloadByteCount < usLength-4){
			ucBytePayload = psPayloadByte[siPayloadByteCount];
			crc ^= ucBytePayload;
			crc = crctab[crc & 0xf] ^ (crc >> 4);
			crc = crctab[crc & 0xf] ^ (crc >> 4);
		}
		else{
			if(crc_count == 0){
				crc = crc ^ 0xffffffffU;
			}
			ucBytePayload = (crc >> (8*crc_count)) & 0xFF;
			crc_count++;
		}

        siPayloadByteCount++;

		for(i=0; i<8; i++)
		{
	        siPayloadBitCount++;

	        ucBit = ucBytePayload & 0x1;
	        ucBytePayload >>= 1;

			ucInputBit   = ucStateTable1Bit[ucScramState]^ucBit;
			ucScramState >>= 1;
			ucScramState |= (ucInputBit << 6);

			usDiffSymbIndex = ucPrevSymb^ucInputBit;
			ucPrevSymb = usDiffSymbIndex;

			psTxOut = &(ssDBPSKTbl[usDiffSymbIndex*2*DUAL_BUF_QUARTER_SIZE]);

			__sb_rcopy(psTxOutDtoAPtrI, psTxOut);
			__sb_rcopy(psTxOutDtoAPtrI+16, psTxOut+16);
			__sb_rcopy(psTxOutDtoAPtrQ, psTxOut+24);
			__sb_rcopy(psTxOutDtoAPtrQ+16, psTxOut+24+16);

			psTxOutDtoAPtrI += (22);
			psTxOutDtoAPtrQ += (22);
		}

		//tic2 = __sb_cfsr(MACH_CYC);
		//__putstring("cyc = %d\n", tic2-tic1);

		/** Wait till prev sub-buffer is Txmitted **/
		wait_sub_buffer_filled();
		reset_sub_buffer_interrupt();

		subbuff_toggle ^= 1;
		psTxOutDtoAPtrI = psTxDtoAStartI +
					  	  subbuff_toggle*SUB_BUF_SIZE_TX;
		psTxOutDtoAPtrQ = psTxDtoAStartQ +
					  	  subbuff_toggle*SUB_BUF_SIZE_TX;

        if(siPayloadBitCount == (usLength*8))
        {
          *ePhyState  = PHY_STATE_SWITCH_OFF_TH;
           break;
        }/* if siStateCount */

    }

    /** Wait till last sub-buffer is Txmitted **/
    wait_sub_buffer_filled();
	reset_sub_buffer_interrupt();

	HS_PhyTx11bPtrTh1->tx_status_l = HS_COMPLETE;

}


